package net.ibizsys.eclipse.studio.dialog;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import net.ibizsys.eclipse.studio.Activator;
import net.ibizsys.eclipse.studio.api.APIManager;
import net.ibizsys.eclipse.studio.api.ActionResult;
import net.ibizsys.eclipse.studio.console.Console;
import net.ibizsys.eclipse.studio.data.IBizApp;
import net.ibizsys.eclipse.studio.data.IBizSolution;
import net.ibizsys.eclipse.studio.data.IBizSystem;
import net.ibizsys.eclipse.studio.data.IBizUser;
import net.ibizsys.eclipse.studio.data.LocalDataManager;
import net.ibizsys.eclipse.studio.data.Project;
import net.ibizsys.eclipse.studio.i18n.I18n;
import net.ibizsys.eclipse.studio.tree.IBizLazyTreeContentProvider;
import net.ibizsys.eclipse.studio.tree.IBizTreeDoubleClickListener;
import net.ibizsys.eclipse.studio.tree.IBizTreeNode;
import net.ibizsys.eclipse.studio.tree.IBizTreeTextLabelProvider;
import net.ibizsys.eclipse.studio.vc.SystemVCManager;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;

/**
 * 主界面窗口
 * 
 * @author <a href='http://www.weibo.com/xjtoo' target='_blank'>Enmaai</a>
 */
public class MainViewDialog extends BaseViewDialog
{
	private TreeViewer viewer;
	private Button checkoutButton;
	private Button downloadButton;

	public MainViewDialog(Shell parentShell)
	{
		super(parentShell);
	}

	@Override
	protected Control createDialogArea(Composite parent)
	{
		getShell().setText(I18n.MainWindowTitle);

		Composite container = (Composite) super.createDialogArea(parent);

		GridData griddata = new GridData(GridData.FILL_BOTH);
		griddata.heightHint = defHeight();
		griddata.widthHint = defWidth();
		container.setLayoutData(griddata);

		createUserInfoArea(container);

		createProjectArea(container);

		onRefresh();

		return container;
	}

	@Override
	protected void createButtonsForButtonBar(Composite parent)
	{
		createButton(parent, IDialogConstants.OK_ID, I18n.Close, false);
	}

	/**
	 * 创建用户信息区
	 * 
	 * @param compsoite
	 */
	private void createUserInfoArea(Composite compsoite)
	{
		IBizUser user = Activator.getDefault().curUser();

		Group group = new Group(compsoite, SWT.NONE);
		group.setText(I18n.UserInfoTitle);

		GridData griddata = new GridData(GridData.FILL_HORIZONTAL);
		griddata.heightHint = userInfoHeight();
		group.setLayoutData(griddata);

		group.setLayout(new GridLayout(4, false));

		Label accountLabel = new Label(group, SWT.NONE);
		accountLabel.setText(I18n.Account);
		Text accountText = new Text(group, SWT.NONE);
		accountText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
		accountText.setText(user.getAccount());
		accountText.setEditable(false);

		Label userLabel = new Label(group, SWT.NONE);
		userLabel.setText(I18n.Username);
		Text userText = new Text(group, SWT.NONE);
		userText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
		userText.setText(user.getName());
		userText.setEditable(false);

		new Label(group, SWT.NONE);
		new Label(group, SWT.FILL).setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		Button logoutButton = new Button(group, SWT.PUSH);
		logoutButton.setText(I18n.Logout);

		logoutButton.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseUp(MouseEvent e)
			{
				onLogoutClicked();
			}
		});
	}

	/**
	 * 创建用户信息区
	 * 
	 * @param compsoite
	 */
	private void createProjectArea(Composite compsoite)
	{
		Group group = new Group(compsoite, SWT.FILL);
		group.setText(I18n.ProjectTitle);
		group.setLayoutData(new GridData(GridData.FILL_BOTH));
		group.setLayout(new GridLayout(5, false));

		viewer = new TreeViewer(group, SWT.VIRTUAL);
		viewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
		viewer.setLabelProvider(new DelegatingStyledCellLabelProvider(new IBizTreeTextLabelProvider()));
		viewer.setContentProvider(new TreeDataProvider(viewer));
		viewer.addDoubleClickListener(new IBizTreeDoubleClickListener(viewer));
		viewer.setUseHashlookup(true);

		viewer.getTree().addSelectionListener(new SelectionListener()
		{
			@Override
			public void widgetSelected(SelectionEvent event)
			{
				onSelectionChanged();
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent event)
			{
				onSelectionChanged();
			}
		});

		Composite composite = new Composite(group, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 5, 1));
		composite.setLayout(new GridLayout(6, false));

		Button refreshButton = new Button(composite, SWT.PUSH);
		refreshButton.setText(I18n.Refresh);
		refreshButton.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseUp(MouseEvent e)
			{
				onRefresh();
			}
		});
		infoLabel = new Label(composite, SWT.NONE);
		infoLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1));
		infoLabel.setForeground(compsoite.getDisplay().getSystemColor(SWT.COLOR_RED));

		downloadButton = new Button(composite, SWT.PUSH);
		downloadButton.setText(I18n.Download);
		downloadButton.setToolTipText(I18n.DownloadToolTip);
		downloadButton.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseUp(MouseEvent event)
			{
				onDownloadSystemClicked();
			}
		});

		checkoutButton = new Button(composite, SWT.PUSH);
		checkoutButton.setText(I18n.Checkout);
		checkoutButton.setEnabled(false);
		checkoutButton.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseUp(MouseEvent event)
			{
				onCheckoutClicked();
			}
		});

		onRefresh();
	}

	private void onLogoutClicked()
	{
		APIManager.logout();
		Activator.getDefault().logout();

		MainViewDialog.this.close();
		new LoginViewDialog(MainViewDialog.this.getShell()).open();
	}

	/**
	 * 树选中变化
	 */
	private void onSelectionChanged()
	{
		if (viewer.getTree().getSelection().length > 0)
		{
			TreeItem treeItem = viewer.getTree().getSelection()[0];

			IBizTreeNode node = (IBizTreeNode) treeItem.getData();
			if (node.getData() instanceof Project)
			{
				Project project = (Project) node.getData();

				project.setChecked(!project.isChecked());

				viewer.refresh(node);
			}
			if (node.getData() instanceof IBizSolution)
			{
				checkoutButton.setEnabled(false);
			} else
			{
				checkoutButton.setEnabled(true);
			}
		} else
		{
			checkoutButton.setEnabled(false);
		}
	}

	/**
	 * 刷新项目数据
	 */
	private void onRefresh()
	{
		if (isBusy())
		{
			return;
		}

		showHUD(I18n.Loading);

		new Thread()
		{
			public void run()
			{
				final ActionResult<IBizSolution> callResult = APIManager.findSolutions(IBizSolution.class);

				hideHUD();

				runOnUIThread(new Runnable()
				{
					@Override
					public void run()
					{
						List<IBizTreeNode> list = new ArrayList<IBizTreeNode>();

						if (callResult.isOK() && callResult.getItems() != null)
						{
							for (int i = 0; i < callResult.getItems().size(); i++)
							{
								list.add(new IBizTreeNode(callResult.getItems().get(i)));
							}
						} else
						{
							if (callResult.getRetcode() == 2)
							{
								loginAndRefresh();
							} else
							{
								alert(I18n.Error, callResult.getErrorInfo());
							}
						}

						viewer.setInput(list);
						viewer.getTree().setItemCount(list.size());
					}
				});
			}
		}.start();
	}

	/**
	 * 登录并刷新
	 */
	private void loginAndRefresh()
	{
		IBizUser user = Activator.getDefault().curUser();
		final String strHost = user.getRemoteUrl();
		final String strAccount = user.getAccount();
		final String strPWD = user.getPassword();

		showHUD(I18n.Logining);

		new Thread()
		{
			@Override
			public void run()
			{
				try
				{
					ActionResult<IBizUser> callResult = APIManager.login(IBizUser.class, strHost, strAccount, strPWD);

					hideHUD();

					if (!callResult.isOK())
					{
						alert(I18n.Error, callResult.getErrorInfo());
					} else
					{
						IBizUser user = callResult.getData();
						user.setPassword(strPWD);
						user.setRemoteUrl(strHost);
						user.setAccount(strAccount);

						LocalDataManager.manager().saveUser(user);
						Activator.getDefault().login(user);

						// 刷新当前
						onRefresh();
					}
				} catch (Exception ex)
				{
					alert(I18n.Error, I18n.SaveLocalError);
				}
			}
		}.start();
	}

	/**
	 * 下载系统数据
	 */
	private void onDownloadSystemClicked()
	{
		if (viewer.getTree().getSelectionCount() == 0)
		{
			alert(I18n.Error, "请先选中系统");
			return;
		}

		IBizTreeNode treeNode = (IBizTreeNode) viewer.getTree().getSelection()[0].getData();

		if (treeNode.getData() instanceof IBizSystem)
		{
			boolean saveResult = LocalDataManager.manager().saveSystem((IBizSystem) treeNode.getData());

			if (saveResult)
			{
				alert("", "保存成功.");
			} else
			{
				alert(I18n.Error, "保存失败.");
			}
		} else
		{
			alert(I18n.Error, "请先选中系统");
		}
	}

	/**
	 * 检出选中系统
	 */
	private void onCheckoutClicked()
	{
		if (viewer.getTree().getSelectionCount() == 0)
		{
			return;
		}
		TreeItem treeItem = viewer.getTree().getSelection()[0];

		IBizTreeNode treeNode = (IBizTreeNode) treeItem.getData();

		if (treeNode.getData() instanceof Project)
		{
			treeNode = (IBizTreeNode) treeNode.getParent();
		}

		if (treeNode.getData() instanceof IBizSystem)
		{
			List<Project> list = new ArrayList<Project>();
			for (IBizTreeNode node : treeNode.getChildren())
			{
				Project project = (Project) node.getData();
				if (project.isChecked())
				{
					list.add(project);
				}
			}
			if (list.size() > 0)
			{
				checkoutProjects((IBizSystem) treeNode.getData(), list);
			}
		}
	}

	/**
	 * 检出项目
	 * 
	 * @param system
	 * @param projects
	 */
	private void checkoutProjects(final IBizSystem system, final List<Project> projects)
	{
		new Thread()
		{
			@Override
			public void run()
			{
				LocalDataManager.manager().saveSystem(system);

				final List<Project> list = SystemVCManager.checkout(system, projects);

				/*
				 * Project webProject = null; for(Project project : list) {
				 * if(project.getType() == ProjectType.WEBUSR) { webProject =
				 * project; break; } }
				 * 
				 * if(webProject != null) { //创建批处理文件
				 * AppBuilder.buildBatch(webProject, list); }
				 */

				MainViewDialog.this.runOnUIThread(new Runnable()
				{
					@Override
					public void run()
					{
						importProjects(list);
					}
				});
			}
		}.start();
	}

	/**
	 * 导入项目到工作区间
	 * 
	 * @param list
	 */
	private void importProjects(final List<Project> list)
	{
		try
		{
			new ProgressMonitorDialog(getShell()).run(true, true, new IRunnableWithProgress()
			{
				@Override
				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
				{
					for (Project proj : list)
					{
						IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(proj.getName());
						if (project != null)
						{
							try
							{
								project.create(monitor);
								project.open(monitor);

								Console.println("[信息]成功导入项目[" + project.getName() + "].");
							} catch (CoreException e)
							{
								Console.println("[错误]导入项目[" + project.getName() + "]失败.");
							}
						} else
						{
							Console.println("[错误]无法获取项目[" + proj.getName() + "],跳过.");
						}
					}
					Console.println("[信息]导入项目结束.");
				}
			});
		} catch (Exception e)
		{
			Console.println("[错误]获取项目执行线程异常,无法导入项目,导入项目终止.");
		}
	}

	private class TreeDataProvider extends IBizLazyTreeContentProvider
	{
		public TreeDataProvider(TreeViewer viewer)
		{
			super(viewer);
		}

		@Override
		protected void onUpdateChildCount(IBizTreeNode node)
		{
			if (node.getChildren().size() <= 0 && node.getData() instanceof IBizSolution)
			{
				ActionResult<IBizSystem> callResult = APIManager.findSystems(IBizSystem.class, ((IBizSolution) node.getData()).getSlnid());
				if (callResult.isOK() && callResult.getItems() != null)
				{
					for (int i = 0; i < callResult.getItems().size(); i++)
					{
						IBizSystem ibizSystem = callResult.getItems().get(i);
						IBizTreeNode systemNode = new IBizTreeNode(ibizSystem);
						systemNode.setParent(node);
						node.addChild(systemNode);

						for (Project ibizProject : ibizSystem.getProjects())
						{
							IBizTreeNode projectNode = new IBizTreeNode(ibizProject);
							projectNode.setParent(systemNode);

							systemNode.addChild(projectNode);
						}

						for (IBizApp ibizApp : ibizSystem.getApps())
						{
							for (Project ibizProject : ibizApp.getProjects())
							{
								IBizTreeNode projectNode = new IBizTreeNode(ibizProject);
								projectNode.setParent(systemNode);

								systemNode.addChild(projectNode);
							}
						}
					}
				}
			}
			viewer.setChildCount(node, node.getChildren().size());
		}
	}

	/**
	 * 默认窗口宽度
	 * 
	 * @return
	 */
	private int defWidth()
	{
		return (int) (Activator.MainWindowWidth * Activator.screenRate(getShell()));
	}

	/**
	 * 默认窗口高度
	 * 
	 * @return
	 */
	private int defHeight()
	{
		return (int) (Activator.MainWindowHeight * Activator.screenRate(getShell()));
	}

	/**
	 * 用户信息高度
	 * 
	 * @return
	 */
	private int userInfoHeight()
	{
		return (int) (Activator.UserInfoHeight * Activator.screenRate(getShell()));
	}
}
